home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Telnet 2.6.1d1 4⁄26⁄94 Folder / source / ftp / binsubs.c next >
Text File  |  1994-04-13  |  11KB  |  458 lines

  1. /****************************************************************
  2. *    NCSA Telnet for the Macintosh                                *
  3. *                                                                *
  4. *    National Center for Supercomputing Applications                *
  5. *    Software Development Group                                    *
  6. *    152 Computing Applications Building                            *
  7. *    605 E. Springfield Ave.                                        *
  8. *    Champaign, IL  61820                                        *
  9. *                                                                *
  10. *    Copyright (c) 1986-1993,                                    *
  11. *    Board of Trustees of the University of Illinois                *
  12. *****************************************************************
  13. *    MacBinary Subroutines.    
  14. */
  15.  
  16. #ifdef MPW
  17. #pragma segment FTPServer
  18. #endif
  19.  
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <fcntl.h>
  23.  
  24. #include "TelnetHeader.h"
  25. #include "maclook.proto.h"
  26. #include "bkgr.proto.h"
  27. #include "MacBinary.h"
  28. #include "telneterrors.h"
  29. #include "binsubs.proto.h"
  30. #include "translate.proto.h"
  31. #include "debug.h"
  32. #include "DlogUtils.proto.h"    // For WriteZero
  33.  
  34. static    unsigned short    CalculateCRC(unsigned char *ptr, short count, unsigned short crc);
  35. static    void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop);
  36. static    void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop);
  37. static    short isMacBinary(MBHead *p);
  38. static    OSErr bwrite( MBFile *out, char *buffer, long size);
  39. static    void ProcessMBHead (MBFile *out, MBHead *header);
  40.  
  41. extern    MBFile        /* BYU */
  42.     *ftp_mbfp,        /* BYU */
  43.     *mbfp;            /* BYU */
  44.  
  45. #define BLOCKS(x)    ((x+127)/128)
  46. /*#define lmove(f,t)    memmove(f,t,(size_t) 4)        /* BYU LSC */
  47.  
  48. MBHead    *mbh;
  49. char    buffer[128];
  50.  
  51. unsigned short    CalculateCRC(unsigned char *ptr, short count, unsigned short crc)
  52. {
  53.     unsigned short    i;
  54.     
  55.     crc = 0;
  56.     while (count -- > 0) {
  57.         crc = crc ^ (unsigned short)*ptr++ << 8;
  58.         for (i = 0; i < 8; i++)
  59.             if (crc & 0x8000)
  60.                 crc = crc << 1 ^ 0x1021;
  61.             else
  62.                 crc = crc << 1;
  63.     }
  64.     
  65.     return crc;
  66. }
  67.  
  68. void GetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop)
  69. {
  70.     iop->ioNamePtr = name;
  71.     iop->ioVRefNum = volume;
  72.     iop->ioDirID = dirID;
  73.     iop->ioFVersNum = 0;
  74.     iop->ioFDirIndex = 0;
  75.     PBHGetFInfo((HParmBlkPtr) iop, FALSE);
  76. }
  77.  
  78. void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop)
  79. {
  80.     iop->ioNamePtr = name;
  81.     iop->ioVRefNum = volume;
  82.     iop->ioDirID = dirID;
  83.     iop->ioFVersNum = 0;
  84.     iop->ioFDirIndex = 0;
  85.     PBHSetFInfo((HParmBlkPtr) iop, FALSE);
  86. }
  87.  
  88. void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop)
  89. {
  90.     GetFileInfo(volume, dirID, name, iop);
  91.     iop->ioFlFndrInfo.fdType = 'TEXT';
  92.     iop->ioFlFndrInfo.fdCreator = gFTPServerPrefs->TextCreator;
  93.     SetFileInfo(volume, dirID, name, iop);
  94. }
  95.  
  96. short isMacBinary(MBHead *p)
  97. {
  98.     unsigned short    crc;
  99.     
  100.     if ((p->nlen > 0)   &&    (p->nlen < 65)  &&
  101.         (p->zero1 == 0) &&    (p->zero2 == 0) && (p->zero3 == 0))    {    // Assume MB I
  102.             crc = CalculateCRC((unsigned char *)p, 124, 0);
  103.             if (((short)p->crc == crc) && (p->mb2versnum > 128))    {        // Check for MB II
  104.                 if (p->mb2minvers > 129)
  105.                     return(0);            // If vers is greater than 129, leave it alone
  106.                 
  107.                 return (1);                // Valid MB II file.
  108.             }
  109.             else {            
  110.                 p->flags2 = 0;            // So we can use same routines for MB I & II
  111.                 return (1);                // Valid MB I file (we make it a II file on the fly.)
  112.                 }
  113.         }
  114.  
  115.     return(0);                            // Not a Macbinary file            
  116. }
  117.  
  118. long MBsize( MBFile *mbfp)
  119. {
  120.     long size = 0;
  121.     OSErr ret;
  122.     
  123.     ret = GetEOF( mbfp->fd, &size );            /* length of file data fork */
  124.     if (ret != noErr) 
  125.         size = 0;
  126.  
  127.     return(size);
  128. }
  129.  
  130. MBFile *MBopen(char *file, short vrefnum, long dirID, short mode)
  131. {
  132.     MBFile *mbfp;
  133.     OSErr err;
  134.  
  135.     if ((mbfp = (MBFile *) NewPtrClear(sizeof(MBFile))) == NULL)
  136.         return(NULL);
  137.  
  138.     if (gFTPServerPrefs->DoISOtranslation)                // MP: translation method
  139.         trbuf_ftp_mac((unsigned char *)file, strlen(file));
  140.  
  141.     BlockMove(file, mbfp->name, 32);
  142.     if (strlen(file) > 31)
  143.         mbfp->name[31] = 0;
  144.  
  145.     if (gFTPServerPrefs->DoISOtranslation)
  146.         trbuf_mac_ftp((unsigned char *)file, strlen(file));                // MP: translation method
  147.  
  148.     c2pstr((char *)mbfp->name);
  149.     mbfp->vrefnum = vrefnum;
  150.     mbfp->dirID = dirID;
  151.     mbfp->mode = mode;
  152.  
  153.     if ((err = HOpen( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd))) {
  154.         if ((err==-43) && (mode & MB_WRITE)) {
  155.             HCreate( vrefnum, dirID, mbfp->name, gFTPServerPrefs->BinaryCreator,
  156.                         gFTPServerPrefs->BinaryType);
  157.             if (mode & MB_ISASCII)    {
  158.                 HFileParam blah;
  159.                 MakeTextFile(vrefnum, dirID, mbfp->name, &blah);
  160.                 }
  161.                 
  162.             if (HOpen( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd)) 
  163.                 return( 0L);
  164.             }
  165.         else 
  166.             return(0L);
  167.         }
  168.  
  169.     if (mode & MB_APPEND)
  170.         SetFPos(mbfp->fd,fsFromLEOF,0);
  171.  
  172.     mbfp->binary=0;
  173.     mbfp->sector1=1;
  174.     mbfp->fork=0;
  175.     return( mbfp);
  176. }
  177.  
  178. OSErr bwrite( MBFile *out, char *buffer, long size)
  179. {
  180.     long len = size;
  181.     OSErr error = noErr;
  182.  
  183.     if (out->binary) {
  184.         if (out->bytes > 0) {
  185.             if (out->bytes < len) len = out->bytes;
  186.             error= FSWrite( out->fd, &len, buffer);
  187.             out->bytes -= len;
  188.             buffer +=len;
  189.             size -= len;
  190.             }
  191.         if (out->bytes <= 0) {
  192.             if (!out->fork) {
  193.                 out->fork = 1;
  194.                 out->bytes = BLOCKS(out->rlen)*128;
  195.                 SetEOF( out->fd, (long) out->dlen);
  196.                 FSClose( out->fd);
  197.                 if (out->bytes) {
  198.                     HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd);
  199.                     if (size) {
  200.                         len = (long) size;
  201.                         error= FSWrite( out->fd, &len, buffer);
  202.                         }
  203.                     }
  204.                 else
  205.                     out->fd = 0;
  206.                 }
  207.             else SetEOF( out->fd, (long) out->rlen);
  208.             }
  209.         }
  210.     else {
  211.         error = FSWrite( out->fd, &len, buffer);
  212.         }
  213.     return (error);
  214. }
  215.  
  216. void ProcessMBHead (MBFile *out, MBHead *header)
  217. {
  218.     OSErr    err;
  219.  
  220.     BlockMove(header, &out->header, sizeof(MBHead));
  221.     out->binary = 1;
  222.     BlockMove(&header->dflen[0], &out->dlen, 4);
  223.     BlockMove(&header->rflen[0], &out->rlen, 4);
  224.     out->bytes = BLOCKS(out->dlen)*128;
  225.     out->fork = 0;
  226.     out->sector1 = 0;
  227.  
  228.     FSClose(out->fd);
  229.     if (HDelete( out->vrefnum, out->dirID, out->name))            /* Error deleting Old File */
  230.         DoError (200 | RESOURCE_ERRORCLASS, LEVEL1, NULL);
  231.         
  232.     BlockMove(&out->header.nlen, out->name, 32);
  233.  
  234. #if 0                                                            /* BYU 2.4.17 */
  235.     MBstat( &out->header.nlen, 1, (long)(BLOCKS(out->dlen)+BLOCKS(out->rlen)) );
  236. #endif                                                            /* BYU 2.4.17 */
  237.  
  238.     if (out->bytes) {
  239.         if ((err=HOpen( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd))) {
  240.             if (err=-43) {
  241.                 long    cre,typ;
  242.                 
  243.                 BlockMove(out->header.type, &typ,  4);
  244.                 BlockMove(out->header.creator, &cre, 4);
  245.  
  246.                 HCreate( out->vrefnum, out->dirID, out->name, cre, typ);
  247.                 if (HOpen(out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) 
  248.                     return;
  249.                 }
  250.             else {
  251.                 return;
  252.                 }
  253.             }
  254.         }
  255.     else {
  256.         if ((err=HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd))) {
  257.             if (err=-43) {
  258.                 long    cre,typ;
  259.  
  260.                 BlockMove(out->header.type, &typ, 4);
  261.                 BlockMove(out->header.creator, &cre, 4);
  262.  
  263.                 HCreate( out->vrefnum, out->dirID, out->name, cre, typ);
  264.                 if (HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) 
  265.                     return;
  266.                 }
  267.             else {
  268.                 return;
  269.                 }
  270.             }
  271.         out->fork = 1;
  272.         out->bytes=BLOCKS(out->rlen)*128;
  273.         }
  274. }
  275.  
  276. long MBwrite(
  277.     MBFile *out,
  278.     void *buffer,    /* BYU LSC */
  279.     long size
  280.   )
  281. {
  282.     long    rsize;
  283.     
  284.     if (size < 1)
  285.         return(0);
  286.  
  287.     rsize=size;
  288.  
  289.     if (out->sector1 && (size >= sizeof(struct MBHead)) &&
  290.         isMacBinary((MBHead *) buffer) && (!(out->mode & MB_DISABLE))) {    /* BYU LSC */
  291. //        putln("First sector MacBinary file");        /* BYU LSC */
  292.         ProcessMBHead( out, (MBHead *) buffer);
  293.         buffer = (void *)((char *)buffer + 128);        /* BYU LSC */
  294.         if ((size-=128) <1)
  295.             return(rsize);
  296.         }
  297.  
  298.     if (bwrite( out,buffer,size))
  299.         return(-1);
  300.     else
  301.         return( rsize);
  302. }
  303.  
  304. void MBclose( MBFile *out)
  305. {
  306.     HFileParam finfo;
  307.     long fpos;
  308.     
  309.     if (!out->fd) {
  310.         if (out != NULL) DisposPtr((Ptr)out);
  311.         return;
  312.         }
  313.  
  314.     if (!(out->mode & MB_DISABLE) && (out->mode & MB_WRITE)) {
  315.         if (out->fork)
  316.             SetEOF( out->fd, (long) out->rlen);
  317.         else
  318.             SetEOF( out->fd, (long) out->dlen);
  319.  
  320.         FSClose( out->fd);
  321.  
  322.         GetFileInfo( out->vrefnum, out->dirID, out->name, &finfo);
  323.         BlockMove(&out->header.type[0], &finfo.ioFlFndrInfo, sizeof(FInfo));
  324.         BlockMove(&out->header.cdate[0], &finfo.ioFlCrDat, 4);
  325.         BlockMove(&out->header.mdate[0], &finfo.ioFlMdDat, 4);
  326.         finfo.ioFlFndrInfo.fdFlags &= 0xfeff;
  327.         finfo.ioFlFndrInfo.fdFlags |= (out->header.flags2 & 0x00FF);
  328.         finfo.ioFlRLgLen=out->rlen;
  329.         finfo.ioFlLgLen =out->dlen;
  330.     
  331.         SetFileInfo( out->vrefnum, out->dirID, out->name, &finfo);
  332.         }
  333.     else if (out->mode & MB_WRITE) {
  334.         GetFPos( out->fd, &fpos);
  335.         SetEOF(  out->fd,  fpos);
  336.         FSClose( out->fd);
  337.         }
  338.     else
  339.         FSClose( out->fd);
  340.     
  341.     DisposPtr((Ptr) out);                    /* JMB 2.6 -- Nice memory leak, no? */
  342. }
  343.  
  344. long MBread
  345.   (
  346.     MBFile *in,
  347.     void *buffer,
  348.     long size
  349.   )
  350. {
  351.     char            *p;
  352.     long            rsize=size;
  353.     unsigned short    crc;
  354.  
  355.     if (in->fork<0) {
  356.         return(-1);
  357.         }
  358.  
  359.     p = buffer;
  360.     
  361.     if (in->sector1) {
  362.         HFileParam finfo;
  363.  
  364. //        setmem( &in->header, sizeof(MBHead), 0);
  365.         WriteZero((Ptr)&in->header, sizeof(MBHead));
  366.         BlockMove(in->name, &in->header.nlen, (Length(in->name) > 31) ? 32 : (Length(in->name)+1));
  367.         GetFileInfo( in->vrefnum, in->dirID, in->name, &finfo);
  368.         BlockMove(&finfo.ioFlFndrInfo, &in->header.type[0], sizeof(FInfo) );
  369.         in->header.flags2 = finfo.ioFlFndrInfo.fdFlags & 0x00FF;
  370.         in->header.protected = (in->header.zero2 & 0x40)?1:0;
  371.         in->header.zero2 = 0;
  372.         BlockMove(&finfo.ioFlLgLen, &in->header.dflen[0], 4);
  373.         BlockMove(&finfo.ioFlRLgLen, &in->header.rflen[0], 4);
  374.         BlockMove(&finfo.ioFlCrDat, &in->header.cdate[0], 4);
  375.         BlockMove(&finfo.ioFlMdDat, &in->header.mdate[0], 4);
  376.         in->header.mb2versnum = 129;
  377.         in->header.mb2minvers = 129;
  378.         crc = CalculateCRC((unsigned char *) &(in->header), 124, 0);
  379.         BlockMove(&crc, &(in->header.crc), 2);
  380.         
  381.         in->dlen=finfo.ioFlLgLen;
  382.         in->rlen=finfo.ioFlRLgLen;
  383.         
  384.         if (! (in->mode & MB_DISABLE) ) {
  385.             if (size<128) return(-1);
  386.  
  387.             BlockMove(&in->header, p, 128);
  388.             p +=128;
  389.             size -= 128;
  390.             in->bytes= BLOCKS(in->dlen)*128;
  391.             in->binary=1;
  392.             }
  393.         else {
  394.             in->bytes = in->dlen;
  395.             in->rlen=0;
  396.             in->binary=0;
  397.             }
  398.         in->sector1=0;
  399. #if 0                                                            /* BYU 2.4.17 */
  400.         MBstat( &in->header.nlen, 1, (long) (BLOCKS(in->dlen)+BLOCKS(in->rlen)) );
  401. #endif                                                            /* BYU 2.4.17 */
  402.         }
  403.  
  404.     if ( size >0) {
  405.         long length = size;
  406.         OSErr err;
  407.  
  408.         err = FSRead( in->fd, &length, p);
  409.  
  410.         size -= length;
  411.         in->bytes -=length;
  412.         p += length;
  413.  
  414.         if (err == -39 || (in->bytes<=0) ) {
  415.             FSClose( in->fd );
  416.             if (in->bytes<0L) in->bytes=0L;
  417. //            setmem(p, in->bytes, 0);            //    Make filler bytes zero
  418.             WriteZero(p, in->bytes);
  419.             size -= in->bytes;
  420.             p    +=      in->bytes;                /* Make adjustments for necessary 128 byte term */
  421.             if (!in->fork ) {
  422.                 in->fork=1;
  423.                 in->bytes= BLOCKS(in->rlen)*128;
  424.                 if (in->bytes) {
  425.                     HOpenRF( in->vrefnum, in->dirID, in->name, fsRdWrPerm, &in->fd);
  426. #ifdef READ
  427.                     length=(long)size;
  428.                     if (length >0L) {
  429.                         err = FSRead( in->fd, &length, p);
  430.                         size -= length;
  431.                         in->bytes -=length;
  432.                         }
  433. #endif READ
  434.                     }
  435.                 else {
  436.                     in->fd=0;
  437.                     in->fork=-1;                    /* Time to close up shop */
  438.                     }
  439.                 }
  440.             else {
  441.                 in->fd=0;
  442.                 in->fork=-1;                    /* Time to close up shop */
  443.                 }
  444.             }
  445.         }
  446.     return( rsize-size); 
  447. }
  448.  
  449. void init_mb_files(void) {            /* BYU */
  450.   ftp_mbfp->fd = 0;            /* BYU */
  451.   mbfp->fd = 0;                /* BYU */
  452. }                            /* BYU */
  453.                             /* BYU */
  454. void close_mb_files(void) {            /* BYU */
  455.     if (ftp_mbfp->fd != 0) MBclose( ftp_mbfp );        /* BYU - close input file */
  456.     if (mbfp->fd != 0) MBclose( mbfp );                /* BYU - close input file */
  457. }                            /* BYU */
  458.